# -*- mode: python ; coding: utf-8 -*-
import sys
import os
from PyInstaller.utils.hooks import collect_all, collect_data_files

block_cipher = None

# 1. 自动收集mediapipe所有依赖
mediapipe_datas, mediapipe_binaries, mediapipe_hiddenimports = collect_all('mediapipe')
# 过滤mediapipe数据文件，适配可能的路径名称（如hand_landmark）
filtered_datas = []
for data in mediapipe_datas:
    # 保留包含"hand"（手部相关）、"framework"（核心框架）的文件
    if 'hand' in data[0].lower() or 'framework' in data[0] or 'calculators/core' in data[0]:
        filtered_datas.append(data)
mediapipe_datas = filtered_datas

# 过滤mediapipe二进制文件（动态链接库等），保留核心依赖
filtered_binaries = []
for src, dest in mediapipe_binaries:
    # 保留手部检测、核心框架相关的二进制文件
    # 排除其他模块（如pose/face/holistic等）的二进制文件
    if 'hands' in src or 'framework' in src or 'calculators/core' in src:
        filtered_binaries.append((src, dest))
mediapipe_binaries = filtered_binaries

# 精简hiddenimports，只保留手部检测和核心框架依赖
mediapipe_hiddenimports = [
    imp for imp in mediapipe_hiddenimports 
    if 'hands' in imp or 'framework' in imp or 'calculators.core' in imp
]
# 3. 修正隐藏导入（移除不存在的模块）
additional_hiddenimports = [
    'torch.distributed._shard.sharding_spec',
    'torch.distributed._shard.sharded_tensor',
    'torch.distributed.checkpoint',
    'mediapipe.calculators',
    'mediapipe.framework',
    'mediapipe.tasks',
]

# 动态获取OpenCV的FFmpeg库路径（如果存在）
opencv_ffmpeg_path = None
cv2_path = os.path.join(sys.base_prefix, 'Lib', 'site-packages', 'cv2')
if os.path.exists(cv2_path):
    for file in os.listdir(cv2_path):
        if file.startswith('opencv_videoio_ffmpeg') and file.endswith('.dll'):
            opencv_ffmpeg_path = os.path.join(cv2_path, file)
if not opencv_ffmpeg_path:
    lib_bin_path = os.path.join(sys.base_prefix, 'Library', 'bin')
    if os.path.exists(lib_bin_path):
        for file in os.listdir(lib_bin_path):
            if file.startswith('opencv_videoio_ffmpeg') and file.endswith('.dll'):
                opencv_ffmpeg_path = os.path.join(lib_bin_path, file)

additional_binaries = []
if opencv_ffmpeg_path and os.path.exists(opencv_ffmpeg_path):
    additional_binaries.append((opencv_ffmpeg_path, '.'))

a = Analysis(
    ['CV_Hanoi.py'],
    pathex=[os.path.abspath('.')],
    binaries=mediapipe_binaries + additional_binaries,
    datas=mediapipe_datas + [
        ('simhei.ttf', '.'),
        ('ico.ico', '.'),
        (os.path.join(sys.base_prefix, 'Lib', 'site-packages', 'mediapipe', 'modules'), 'mediapipe/modules'),
    ],
    hiddenimports=mediapipe_hiddenimports + additional_hiddenimports + [
        'cv2', 'numpy', 'PIL',
        'matplotlib', 'matplotlib.pyplot', 'matplotlib.backends.backend_agg',
        'matplotlib.backends', 'matplotlib.figure',
        'numpy.core._dtype_ctypes', 'numpy.fft',
    ],
    hookspath=[],
    hooksconfig={'matplotlib': {'backend': 'Agg'}},
    runtime_hooks=[],
    excludes=[
        'tensorflow', 'pandas', 'scipy', 'numpy.testing',
        'torch.testing', 'setuptools.distutils_patch',
        'torch.onnx',  # 排除不使用的torch.onnx模块，减少警告
    ],
    win_no_prefer_redirects=False,
    win_private_assemblies=False,
    cipher=block_cipher,
    noarchive=False,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)

exe = EXE(
    pyz,
    a.scripts,
    a.binaries,
    a.zipfiles,
    a.datas,
    [],
    name='手势控制汉诺塔',
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=True,
    upx_exclude=[
        'python3.dll', '_uuid.pyd', 'torch.dll', 'torch_global_deps.dll',
        'jaxlib*.pyd', 'mlir*.pyd',
        'onnxruntime.dll', 'onnxruntime_providers_shared.dll',
        'msvcp140.dll', 'vcruntime140.dll', 'vcruntime140_1.dll',
    ],
    runtime_tmpdir=None,
    console=True,  # 若运行出错，可临时改为True查看控制台日志
    disable_windowed_traceback=False,
    argv_emulation=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None,
    icon='ico.ico',
)